package com.xx.system.jwt;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.HashMap;
import java.time.Instant;

/**
 * TODO
 *
 * @Author kzw
 * @Date 2025/4/2 09:35
 */
public class JWTUtil {

    // 密钥与桥梁编码的映射关系
    private static final Map<String, String> BRIDGE_KEY_MAP = new HashMap<>();

    static {
        BRIDGE_KEY_MAP.put("G526330921L0120", "gkegdw8sxt5wmndes8aanmq5ukvw4phwsjr8cdmyygcgfwvv8j48zgujfwh3efrv");
        BRIDGE_KEY_MAP.put("G526330921L0130", "dt9n7rqar7wn4dc6ffwjx3tjwyff8fdgr75vtpny4bskbm9dday6d44dz4pammsq");
        BRIDGE_KEY_MAP.put("G9211330902L0019", "e58da6dv9j9nsn8jtb7n3bnyk2exhcud7zudmk376k54m8hngvgjbck93bhh7wny");
        BRIDGE_KEY_MAP.put("G9211330902L0027", "9duh2grarjvktm3j6gc7j9gsznjw49pm347hevytjemzypfe4nq2ahbua2b666js");
        BRIDGE_KEY_MAP.put("G9211330902L0008", "8ktku9vkvbu2qu2kpnayzvqryksa5nek6s6gtf4pzd6d8mes4hfvjxpeqbduc6xg");
        BRIDGE_KEY_MAP.put("S6330902L0029", "npte7qhvkdhbpfeqrwwfq7vwea6vzuch7s34mj48cy92z3mgqvxvz8tuav8nsgsm");
        BRIDGE_KEY_MAP.put("S6330902L0010", "ecmaz5npkgbs38j7nb5hukx2c9cwntq964fms83n7sjr5m3p9r8x468udme7jj9c");
        BRIDGE_KEY_MAP.put("24013309520401141714", "52ztzfqmm6a4x8ayuzxmqv9ctcrbttm5mqed7ks2kvwr64t4z2kxzzp25s3dey5c");
        BRIDGE_KEY_MAP.put("24013309520401141715", "rua58m8j9res3vcawy2ybqwd45myeah852hynh9cuacc5yevbv5wyggh579f22xx");
        // 可以根据需要继续添加更多的桥梁编码和密钥
    }

    // 10分钟有效期
    private static final long JWT_EXPIRATION_TIME_MS = 10 * 60 * 1000; // 10分钟有效期

    // Base64 URL安全编码
    public static String base64UrlEncode(byte[] data) {
        return Base64.getUrlEncoder().withoutPadding().encodeToString(data);
    }

    // 创建JWT头部
    public static String createHeader() {
        Map<String, Object> header = new HashMap<>();
        header.put("type", "JWT");
        header.put("alg", "SM3");
        String headerJson = toJson(header);
        return base64UrlEncode(headerJson.getBytes(StandardCharsets.UTF_8));
    }

    // 创建JWT载荷
    public static String createPayload(String bridgeUniqueCode, long seq, long timestamp) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("bridgeUniqueCode", bridgeUniqueCode);
        payload.put("seq", seq);
        payload.put("timestamp", timestamp);
        String payloadJson = toJson(payload);
        return base64UrlEncode(payloadJson.getBytes(StandardCharsets.UTF_8));
    }

    // 创建签名
    public static String createSignature(String header, String payload, String secretKey) {
        try {
            String data = header + "." + payload;
            byte[] key = secretKey.getBytes(StandardCharsets.UTF_8);
            HMac hmac = new HMac(new SM3Digest());
            hmac.init(new KeyParameter(key));
            hmac.update(data.getBytes(StandardCharsets.UTF_8), 0, data.length());
            byte[] signature = new byte[hmac.getMacSize()];
            hmac.doFinal(signature, 0);
            return base64UrlEncode(signature);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 根据桥梁编码生成JWT Token,打印Token生成时的各部分内容
    public static String generateJWT(String bridgeUniqueCode, long seq) {
        String header = createHeader();
        long timestamp = Instant.now().toEpochMilli();  // 当前时间戳
        String payload = createPayload(bridgeUniqueCode, seq, timestamp);
        String signature = createSignature(header, payload, BRIDGE_KEY_MAP.get(bridgeUniqueCode));

        System.out.println("Generated JWT Header: " + header);
        System.out.println("Generated JWT Payload: " + payload);
        System.out.println("Generated JWT Signature: " + signature);

        return header + "." + payload + "." + signature;
    }

    // 将JWT Token放到HTTP请求头中
    public static String getAuthorizationHeader(String bridgeUniqueCode, long seq) {
        String jwtToken = generateJWT(bridgeUniqueCode, seq);
        return "bridgeToken: Bearer " + jwtToken;  // 按照格式放置在HTTP Header中
    }

    // 验证JWT Token,打印接收到的Token和计算出的签名
    public static boolean verifyToken(String token) {
        String[] parts = token.split("\\.");
        if (parts.length != 3) {
            return false;
        }
        String header = parts[0];
        String payload = parts[1];
        String signature = parts[2];

        System.out.println("Received Header: " + header);
        System.out.println("Received Payload: " + payload);
        System.out.println("Received Signature: " + signature);

        String bridgeUniqueCode = getBridgeUniqueCodeFromPayload(payload);
        String secretKey = BRIDGE_KEY_MAP.get(bridgeUniqueCode);
        if (secretKey == null) {
            return false;
        }

        String calculatedSignature = createSignature(header, payload, secretKey);
        System.out.println("Calculated Signature: " + calculatedSignature);

        return signature.equals(calculatedSignature);
    }

    // 从载荷中获取时间戳
    private static long getTimestampFromPayload(String payload) {
        String decodedPayload = new String(Base64.getUrlDecoder().decode(payload), StandardCharsets.UTF_8);
        Map<String, Object> map = parseJsonToMap(decodedPayload);
        return Long.parseLong(map.get("timestamp").toString());
    }

    // 从载荷中解析桥梁编码
    private static String getBridgeUniqueCodeFromPayload(String payload) {
        String decodedPayload = new String(Base64.getUrlDecoder().decode(payload), StandardCharsets.UTF_8);
        Map<String, Object> map = parseJsonToMap(decodedPayload);
        return (String) map.get("bridgeUniqueCode");
    }

    // 将对象转换为JSON字符串
    private static String toJson(Map<String, Object> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sb.append("\"").append(entry.getKey()).append("\": ");
            sb.append("\"").append(entry.getValue()).append("\", ");
        }
        sb.delete(sb.length() - 2, sb.length()); // 去掉最后的逗号
        sb.append("}");
        return sb.toString();
    }

    // 简单的JSON解析工具，将JSON字符串转为Map
    private static Map<String, Object> parseJsonToMap(String json) {
        Map<String, Object> map = new HashMap<>();
        json = json.replace("{", "").replace("}", "");
        String[] pairs = json.split(",");
        for (String pair : pairs) {
            String[] keyValue = pair.split(":");
            map.put(keyValue[0].replace("\"", ""), keyValue[1].replace("\"", ""));
        }
        return map;
    }

    // 示例测试
    public static void main(String[] args) {
        String bridgeUniqueCode = "G526330921L0120"; // 示例桥梁编码
        long seq = 123456;

        // 获取HTTP请求头中的Authorization部分
        String authorizationHeader = getAuthorizationHeader(bridgeUniqueCode, seq);
        System.out.println("Authorization Header: " + authorizationHeader);

        // 验证JWT Token
        String token = authorizationHeader.split(" ")[1]; // 获取Token部分
        boolean isValid = verifyToken(token);
        System.out.println("Is the token valid? " + isValid);
    }
}